package handler;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.ReferenceCountUtil;

import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.Map;

/**
 * @author yuzk
 * @date 2018/1/12
 */
@ChannelHandler.Sharable
public class TcpServerHandler extends ChannelInboundHandlerAdapter{

    private TcpServerHandler() { }

    private static TcpServerHandler handler = new TcpServerHandler();

    public static TcpServerHandler getHandler() {
        return handler;
    }

    private static Map<Integer,Channel> channelMap = new HashMap<>();

    @Override
    public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
        Integer port = ((InetSocketAddress)ctx.channel().remoteAddress()).getPort();
        channelMap.put(port,ctx.channel());
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        try {
            Integer remotePort = ((InetSocketAddress) ctx.channel().remoteAddress()).getPort();
            System.out.println("server receive: " + msg);
            String message = (String) msg;
            ctx.channel().writeAndFlush(remotePort + "==me: " + message);
            String[] splits = message.split("\\:");
            String to = null;
            if (splits.length >= 2) {
                to = splits[0];
            }
            if (to == null) {
                return;
            }
            final String message2 = message.substring(message.indexOf(":") + 1);
            if (to.equals("all")) {
                channelMap.forEach((port, channel) -> {
                    channel.writeAndFlush(remotePort + " : " + message2);
                });
                return;
            }
            if (channelMap.keySet().contains(Integer.valueOf(to))) {
                channelMap.get(Integer.valueOf(to)).writeAndFlush(remotePort + " : " + message);
            }
        }finally {
            ReferenceCountUtil.release(msg);
        }
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        super.channelReadComplete(ctx);
    }
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        super.exceptionCaught(ctx, cause);
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        super.channelActive(ctx);
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        super.channelInactive(ctx);
    }
}
